package com.songtech.server.frame;

import com.songtech.server.entry.BaseProtocal;
import com.songtech.server.frame.route.annotation.Allot;
import com.songtech.server.frame.route.annotation.SettingMethod;
import com.songtech.server.frame.service.BaseService;
import com.songtech.server.frame.service.setting.ISetting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Create By YINN on 2018/4/7 1:28
 * Description : 分配器注册
 */

@Component
public class BaseServiceRegister extends ApplicationObjectSupport {

    private final static Map<String, BaseService> SERVICE_MAP = new ConcurrentHashMap<>();

    private final static Map<String, Class> ENTRY_MAP = new ConcurrentHashMap<>();

    private final static Map<String, ISetting> SETTING_MAP = new ConcurrentHashMap<>();

    @Override
    public void initApplicationContext(ApplicationContext context) throws BeansException {
        super.initApplicationContext(context);
        Map<String, Object> beanMap = context.getBeansWithAnnotation(Allot.class);
        beanMap.keySet().forEach(beanName -> {
            Object bean = beanMap.get(beanName);
            Class clazz = bean.getClass();

            //存入缓存
            if (bean instanceof BaseService && clazz.getAnnotation(Allot.class) != null) {
                Allot allot = (Allot) clazz.getAnnotation(Allot.class);
                String cmd = allot.cmd();
                if (SERVICE_MAP.keySet().contains(cmd)) {
                    throw new RuntimeException("BaseService has Exits. BaseService=" + cmd);
                }
                SERVICE_MAP.put(allot.cmd(), (BaseService) beanMap.get(beanName));
                ENTRY_MAP.put(allot.cmd(),allot.beanClass());

            }

        });

        Map<String, Object> settingBeanMap = context.getBeansWithAnnotation(SettingMethod.class);
        settingBeanMap.keySet().forEach(beanName -> {
            Object bean = settingBeanMap.get(beanName);
            Class clazz = bean.getClass();

            //存入缓存
            if (bean instanceof ISetting && clazz.getAnnotation(SettingMethod.class) != null){
                SettingMethod settingMethod = (SettingMethod) clazz.getAnnotation(SettingMethod.class);
                String cmd = settingMethod.cmd();
                if (SETTING_MAP.keySet().contains(cmd)) {
                    throw new RuntimeException("BaseService has Exits. BaseService=" + cmd);
                }
                SETTING_MAP.put(settingMethod.cmd(), (ISetting) settingBeanMap.get(beanName));
            }

        });

    }

    public static BaseService getService(String cmd) {
        return SERVICE_MAP.get(cmd);
    }

    public static ISetting getISetting(String cmd) {
        return SETTING_MAP.get(cmd);
    }

    public static Class<? extends BaseProtocal> getBeanClass(String cmd){
        return ENTRY_MAP.get(cmd);
    }
}
